﻿#region Using Statements
using Microsoft.Xna.Framework;
#endregion

namespace StarFox.ScreenComponents
{
    /// <summary>
    /// Implementation of a power-up.
    /// </summary>
    public class PowerUp : IAsteroid
    {
        #region Public Data

        /// <summary>
        /// Defines what type a power-up is.
        /// </summary>
        public enum PowerUpType
        {
            /// <summary>
            /// Increase health power-up.
            /// </summary>
            HEALTH,
            /// <summary>
            /// Increase boost power-up.
            /// </summary>
            BOOST,
            /// <summary>
            /// Increase fuel power-up.
            /// </summary>
            FUEL,
            /// <summary>
            /// Extra bomb power-up.
            /// </summary>
            BOMB,
            /// <summary>
            /// Extra life power-up.
            /// </summary>
            LIFE
        };

        /// <summary>
        /// Defines the color corresponding to every type of power-up.
        /// </summary>
        public static Color[] PowerUpColor = new Color[5]
        {
                Color.Chartreuse,
                Color.Aqua,
                Color.Gold,
                Color.Red,
                Color.Fuchsia
        };

        #endregion

        #region Constants

        // rotation velocity
        const float MinRotation = -MathHelper.Pi * 0.005f;
        const float MaxRotation = MathHelper.Pi * 0.005f;

        // movement velocity
        const float MinVelocity = 1.0f;
        const float MaxVelocity = 2.0f;

        #endregion

        #region Fields

        Vector3 position;
        Vector3 movement;
        Vector3 rotation;
        Vector2 rotVel;
        Matrix world;

        #endregion

        #region Properties

        /// <summary>
        /// Gets the type of the power-up. 
        /// </summary>
        public PowerUpType Type { get; private set; }

        /// <summary>
        /// Gets the model index used to draw the power-up.
        /// </summary>
        public int Index { get; private set; }

        /// <summary>
        /// Gets or sets the position of the power-up.
        /// </summary>
        public Vector3 Position
        {
            get { return position; }
            set
            {
                position = value;
                world.Translation = position;
            }
        }

        /// <summary>
        /// Gets or sets the movement direction and velocity of the power-up.
        /// </summary>
        public Vector3 Movement
        {
            get { return movement; }
            set { movement = value; }
        }

        /// <summary>
        /// Gets the world matrix used to draw the power-up.
        /// </summary>
        public Matrix World
        {
            get { return world; }
        }

        #endregion

        #region Constructor

        /// <summary>
        /// Initializes a new instance of this class.
        /// </summary>
        /// <param name="index">The model index used to draw the power-up.</param>
        /// <param name="position">The position of the power-up.</param>
        /// <param name="shipPos">The position of the starship.</param>
        /// <param name="type">The type of the power-up.</param>
        public PowerUp(int index, Vector3 position, Vector3 shipPos, PowerUpType type)
        {
            Index = index;
            this.position = position;
            Type = type;

            rotation = new Vector3(StarFoxHelper.RandomFloat(-MathHelper.Pi, MathHelper.Pi),
                                   StarFoxHelper.RandomFloat(-MathHelper.Pi, MathHelper.Pi),
                                   StarFoxHelper.RandomFloat(-MathHelper.Pi, MathHelper.Pi));

            rotVel = new Vector2(StarFoxHelper.RandomFloat(MinRotation, MaxRotation),
                                 StarFoxHelper.RandomFloat(MinRotation, MaxRotation));

            movement.X = (position.X < shipPos.X) ? 1.0f : -1.0f;
            movement.Y = (position.Y < shipPos.Y) ? 0.25f : -0.25f;
            movement.Z = StarFoxHelper.RandomFloat(-1.0f, 1.0f);
            movement.Normalize();
            movement *= StarFoxHelper.RandomFloat(MinVelocity, MaxVelocity);
        }

        #endregion

        #region Update

        /// <summary>
        /// Called when the power-up needs to be updated.
        /// </summary>
        public void Update()
        {
            world = Matrix.Identity;

            // adjust rotation
            rotation.X += rotVel.X;
            rotation.Y += rotVel.Y;
            world *= Matrix.CreateRotationX(rotation.X);
            world *= Matrix.CreateRotationY(rotation.Y);
            world *= Matrix.CreateRotationZ(rotation.Z);

            // adjust translation
            position += movement;
            world.Translation = position;
        }

        #endregion
    }
}
